#ifndef __encoder_H
#define __encoder_H

#ifdef __cplusplus
extern "C"
{
#endif

#include "sys.h"

    ////////////////////////////////////添加新增接受缓存//////////////////////////////////
    typedef struct
    {
        uint32_t StdId; /*!< Specifies the standard identifier.
                        This parameter can be a value between 0 to 0x7FF. */

        uint32_t ExtId; /*!< Specifies the extended identifier.
                        This parameter can be a value between 0 to 0x1FFFFFFF. */

        uint8_t IDE; /*!< Specifies the type of identifier for the message that 
                        will be received. This parameter can be a value of 
                        @ref CAN_identifier_type */

        uint8_t RTR; /*!< Specifies the type of frame for the received message.
                        This parameter can be a value of 
                        @ref CAN_remote_transmission_request */

        uint8_t DLC; /*!< Specifies the length of the frame that will be received.
                        This parameter can be a value between 0 to 8 */

        uint8_t Data[8]; /*!< Contains the data to be received. It ranges from 0 to 
                        0xFF. */

        uint8_t FMI; /*!< Specifies the index of the filter the message stored in 
                        the mailbox passes through. This parameter can be a 
                        value between 0 to 0xFF */
    } CanRxMsg_new;

    typedef struct
    {
        double angle; /*角度*/

        double cycle; /*圈数 */

        uint8_t ID; /*ID */

        uint8_t ZERO; /*零点值*/

        uint8_t Data[8]; /*编码器返回数据 */

        u8 Encoder_CAN_Read_OK; /////////////0表示成功，1表示失败

    } Encoder;

    typedef struct
    {
        u8 head_1;   /*包头0x0d*/
        u8 head_2;   /*包头0x0a*/
        double body; /*命令 */
        u8 tail_1;   /*包尾0x0d*/
        u8 tail_2;   /*包尾0x0a*/
        u8 now_status;
        /* 数组数据数量           */
    } Frame_Sign;

    /*************************添加控制编码器相对增量角度***************************/
    //#define ENCODER_BIG_GEAR    141     //大齿轮齿数
    //#define ENCODER_SMALL_GEAR  23      //小齿轮齿数

    //#define ENCODER_BIG_GEAR    120     //大齿轮齿数
    //#define ENCODER_SMALL_GEAR  19      //小齿轮齿数

#define ENCODER_BIG_GEAR 141  //大齿轮齿数
#define ENCODER_SMALL_GEAR 19 //小齿轮齿数

#define ENCODER_MAX_ANGLE 8640
#define ENCODER_HALF_MAX_ANGLE 4320

#define NormalizeAngle(a) ((a > ENCODER_HALF_MAX_ANGLE) ? (a - ENCODER_MAX_ANGLE) : (a < -ENCODER_HALF_MAX_ANGLE) ? (a + ENCODER_MAX_ANGLE) \
                                                                                                                  : a)

#define EncoderRelativeAngle 0

    /*************************添加控制编码器相对增量角度***************************/

    extern Frame_Sign Frame_Sign_usart3; //串口解析帧的状态指示位
    extern int Receive_Queue;            // 当前队列数

#define Encoder_ID_1 0X02
#define Encoder_ID_2 0X03
#define Encoder_ID_3 0X04
#define Encoder_ID_4 0X05
#define Zero_S_Len 8

/*************************8.25添加控制编码器程序***************************/
#define Encoder_Angle_Order 0x01
#define Encoder_ID_Order 0x02
#define Encoder_Zero_Order 0x06
#define Encoder_Height_Order 0x07

#define R_Len 40
#define Usart3_R_Len 48
#define Usart3_F1F4_Len 24
#define Encoder_Imu_Len 40

    extern u8 Send_Retutn_data[R_Len];
    extern CanRxMsg_new CanRxMsg_new_store;
    extern u8 Send_OK;
    extern u8 usart3_Receive_Data[Usart3_R_Len];

    void EncoderInit(void);
    u8 CAN1_Send_Read_Angle_Order(u8 can_id);
    u8 CAN1_Send_Set_Zero_Order(u8 can_id);
    u8 CAN1_Send_Set_ID_Order(u8 can_old_Id, u8 can_new_Id);
    u8 Encoder_Uart3_Return_Angle_Data(void);
    u8 Encoder_Uart3_Return_Zero_Status(void);
    //u8 Encoder_delay_1ms(u8 time,u8 Encoder_Read_Flag);
    u8 Encoder_delay_1ms(u8 time, Encoder *encoder);
    u8 Caculate_Encoder_Angle_Data(u8 can_id);
    u8 Caculate_Encoder_Zero_Data(u8 can_id);

    int pow_int(int m, int n);
    /*************************************************************************/

    void Caculate_Update(u8 can_id, int I_Angle);
    u8 loop_qurey_angle(void);

    /***************************************/

    u8 Judge_CRC(void);
    void Analysis_Order(void);
    void Judge_Which_Enocder(u8 nn);
    void Analyze_Zero(u8 Zero_Order[]);
    u8 Encoder_Demarcate_Zero(void);
    u8 Encoder_Demarcate(u8 id);
#define Usart_Initial_number 0x00
#define Usart_0D 0x01
#define Usart_0A 0x02
#define Usart_All_Tail 0x03
#define Usart_CRC 0x04
#define Usart_Faile 0xff

#define F4_Angle_Order 0x01
#define F4_Zero_Order 0x02
#define F4_ID_Order 0x03

#ifdef __cplusplus
}
#endif

#endif
